<?php

class Conquer extends Controller {

	var $tituloListado   = "Listado";
	var $tituloCrear     = "Crear ";
	var $tituloModificar = "Modificar ";
	var $carpetaVista = '';
	var $modelo; // cuidado con usar esta variable!!!
	var $nombreModelo;

	var $paginaActual = '0';
	var $cantidadPorPagina = '20';


	var $namemodPadre  = "";
	var $namemodAbuelo   = "";
	var $namemodHijo   = "";
	var $dataPadre   = "";
	var $dataAbuelo   = "";
	var $metaDataPadre  = "";
	var $metaDataHijo   = "";

	// =================================================
	function Conquer()
	{
		parent::Controller();
		$this->carpetaVista = 'conquer/';
		$this->load->helper(array('html','url','form'));
		$this->load->library('pagination');
		// Definir el nombre de la session
		$this->sesion->setNombreSesion('cms_conquer');

		/**
		 * Verificar que la sesion se autentifico
		 */
		if (!$this->sesion->sesion_valida()){
			redirect('login_control');
		}

		if (!$this->sesion->existe(array('privilegios','conquer','ver'))){

			//$this->sesion->invalidar_sesion();
			//redirect('');
			$this->sesion->set_userdata('error',"<p>No posee permisos para acceder a la secci&oacute;n solicitada.</p>");
			redirect('login_control');
			exit(0);

		}

	}

	// =================================================
	function index()
	{

		$this->home();
	}
	
	function pip(){
		echo 1;
	}

	// =================================================
	function home()
	{
		$data = array();
		$data['titulo_pagina'] = 'Home';
		//$this->load->helper(array('html','url')); // ya se cargan en el controlador
		$this->load->view($this->carpetaVista.'cabecera');
		$this->load->view($this->carpetaVista.'navegacion');
		$this->load->view($this->carpetaVista.'error');
		$this->load->view($this->carpetaVista.'pie');

	}


	// =================================================
	/**
	 * Genera un listado del modelo especificado
	 * // $sinabuelo con valor 1 muestra sin abuelo
	 * @param $model
	 * @param $idpadre
	 * @param $sinabuelo
	 * @return unknown_type listado del modelo especificado
	 */
	function listar($model = NULL, $idpadre=0) // Pasar a: listar($model = NULL, $idpadre=0)
	{
		// Verificar que se selecciono un modelo para listar, sino enviarlo al home
		if (empty($model)) { redirect($this->carpetaVista.'home'); }
		// Guardar el modelo que se esta utilizando y cargarlo.
		$this->nombreModelo = $model;
		$this->load->model($model,'modelo');
		
		$sinabuelo=$this->modelo->getTipoListado();  // FIXME Abajo de Fin Paginacion?
		// Paginacion
		// TODO Verificar Paginacion
		$paramsGet = explode('/',$this->uri->uri_string());
		$pActual = array_pop($paramsGet);
		$anteUltimo = array_pop($paramsGet);
		// p es de pagina porque existe un modelo pagina.
		if ($anteUltimo != 'p') {
			$pActual = 0;
		}
		$this->paginaActual = $pActual;
		if ($idpadre == 'p') { $idpadre=0; $sinabuelo = false; }
		if ($sinabuelo== 'p') { $sinabuelo=false; }
		// Fin Paginacion

		$this->tituloListado = $this->modelo->getTituloListado();


		/**
		 * Resultado de getPartof() ( Array de metadatos del padre si es que lo hay )
		 *   - NULL : En el caso de que no sea parte de nada
		 *   - array() con los metadatos del mismo :
		 *              - Si no se le paso el id del padre, debe listar los padres, scope 2 niveles (el abuelo).
		 *              -
		 */
		$padre = $this->modelo->getPartof();

		if (empty($padre)){  //********En el caso de que no sea parte de nada
			
			if (is_null($this->modelo->getListadoTabla()))
				$this->abmSimple();
			else
				$this->listadoTabla($idpadre);


		}else{				//********En el caso de que sea parte de algo

			if ($idpadre==0){ 	//********Si no se le paso el id del padre, debe listar los padres, scope 2 niveles (el abuelo).

				$this->seleccionDePadre($padre);

			} else {			//********Si se le paso el id del padre, lista todos los hijos, scope 2 niveles (el abuelo)

				$this->abmDeHijos($padre,$idpadre,$sinabuelo);

			}
		}

		//print_r($this->sesion->userdata('privilegios'));
	}

	// =================================================
	/**
	 * Listado Simple
	 * @return unknown_type
	 */
	private function abmSimple() {


		// $config = $this->modelo->secProxy('paginacion');
		$data['titulo_pagina'] = $this->tituloListado;
		$data['modelo'] = $this->nombreModelo;
		$data['metaData'] = $this->modelo->getMetaData();
		$data['resultado'] = $this->modelo->secProxy('getData',$this->cantidadPorPagina, $this->paginaActual);
		$cantidadTotal = $this->modelo->getCantidadRegistros();
		$data['hijosModelo'] = $this->modelo->getHijos();
		$data['extras'] = $this->modelo->getExtras();
		$data['modoriginal'] = '';
		//******** Para las claves foraneas
		//$this->load->helper('recursion_helper');
		recursion($this,$data['metaData'],$data['resultado'],$data['modelo']);

		$dataMenu['modelo'] = $this->nombreModelo;
		$dataMenu['idpadre'] = 0; 
		$dataMenu['listar'] = $this->modelo->mostrarOpcionListar();
		$dataMenu['crear'] = $this->modelo->mostrarOpcionCrear();
		$dataMenu['buscar'] = $this->modelo->mostrarOpcionBuscar();
		
		
		//Se inicializa la paginacion correspondiente.
		$url = site_url('conquer/listar/'.$this->nombreModelo.'/p/');
		$config = $this->paginacion($url,$this->cantidadPorPagina,$cantidadTotal,5 );
		$this->pagination->initialize($config);
		//$data['links'] = $this->pagination->create_links();
		$data['links'] = $config;


		//echo '<pre>'; print_r($this->sesion->userdata('privilegios')); echo '</pre>';

		$this->load->view($this->carpetaVista.'cabecera');
		$this->load->view($this->carpetaVista.'navegacion');
		$this->load->view($this->carpetaVista.'opciones',$dataMenu);
		$this->load->view($this->carpetaVista.'error');
		$this->load->view($this->carpetaVista.'listado',$data);
		$this->load->view($this->carpetaVista.'pie');
	}


	private function listadoTabla($filtro){

		$data['titulo_pagina'] = $this->tituloListado;
		$data['modelo'] = $this->nombreModelo;
		$data['metaData'] = $this->modelo->getMetaData();
		$tieneFiltro=$this->modelo->getFiltro();

		//FILTRO
		if (!empty($tieneFiltro)){
			$filtroMetaData=NULL;
			foreach ($data['metaData'] as $metadata){
				if ($metadata['realname']==$tieneFiltro){
					$filtroMetaData=$metadata;
					break;
				}
			}
			$this->load->model($filtroMetaData['modelo']);
			$datosfiltro=$this->$filtroMetaData['modelo']->secProxy('getIdNombre'); 
			$data['filtro'] = array('name'=>$tieneFiltro, 'id'=>$filtro, 'metadata'=>$filtroMetaData, 'data'=>$datosfiltro);
	
			//FIXME esto es especifico del problema
			if ($filtro=='hoy'){
				$aux=$this->$filtroMetaData['modelo']->secProxy('busqueda_gen',array($tieneFiltro),'now() between fechadesde and fechahasta',1);
				if (!empty($aux['consulta']))
					$filtro=$aux['consulta'][0][$tieneFiltro];
			}

			if ($filtro!=0 && !empty($tieneFiltro))
				 $this->modelo->setCondicion($tieneFiltro,$filtro);
		}
		$data['resultado'] = $this->modelo->secProxy('getData',$this->cantidadPorPagina, $this->paginaActual);
		$cantidadTotal = $this->modelo->getCantidadRegistros();
		$data['hijosModelo'] = $this->modelo->getHijos();
		$data['extras'] = $this->modelo->getExtras();
		$data['modoriginal'] = '';
		$data['listadoTabla'] = $this->modelo->getListadoTabla();

		//FILTRO
		if (!empty($tieneFiltro)){
			$filtroMetaData=NULL;
			foreach ($data['metaData'] as $metadata){
				if ($metadata['realname']==$tieneFiltro){
					$filtroMetaData=$metadata;
					break;
				}
			}
			$this->load->model($filtroMetaData['modelo']);
			$datosfiltro=$this->$filtroMetaData['modelo']->secProxy('getIdNombre'); 
			$data['filtro'] = array('name'=>$tieneFiltro, 'id'=>$filtro, 'metadata'=>$filtroMetaData, 'data'=>$datosfiltro);
		}

		//******** Para las claves foraneas
		//$this->load->helper('recursion_helper');
		recursion($this,$data['metaData'],$data['resultado'],$data['modelo']);

		$dataMenu['modelo'] = $this->nombreModelo;
		$dataMenu['idpadre'] = 0; 
		$dataMenu['listar'] = $this->modelo->mostrarOpcionListar();
		$dataMenu['crear'] = $this->modelo->mostrarOpcionCrear();
		$dataMenu['buscar'] = $this->modelo->mostrarOpcionBuscar();
		
		
		//Se inicializa la paginacion correspondiente.
		$url = site_url('conquer/listar/'.$this->nombreModelo.'/p/');
		$config = $this->paginacion($url,$this->cantidadPorPagina,$cantidadTotal,5 );
		$this->pagination->initialize($config);
		//$data['links'] = $this->pagination->create_links();
		$data['links'] = $config;


		//echo '<pre>'; print_r($this->sesion->userdata('privilegios')); echo '</pre>';

		$this->load->view($this->carpetaVista.'cabecera');
		$this->load->view($this->carpetaVista.'navegacion');
		$this->load->view($this->carpetaVista.'opciones',$dataMenu);
		$this->load->view($this->carpetaVista.'error');
		$this->load->view($this->carpetaVista.'listatabla',$data);
		$this->load->view($this->carpetaVista.'pie');
		
	}
	// =================================================
	/**
	 * Listado con padre y posiblemente abuelo
	 * @param $padre
	 * @param $idpadre
	 * @param $sinabuelo
	 * @return unknown_type
	 */
	private function abmDeHijos($padre,$idpadre,$sinabuelo) {


		//$this->load->helper(array('form', 'url'));

		$this->namemodHijo=$this->nombreModelo;
		//$cantidadTotal = backtrack($this,$idpadre,$sinabuelo,$this->cantidadPorPagina, $this->paginaActual);
		backtrack($this,$idpadre,$sinabuelo);

		//Carga el Arbol de navegacion
		$arbol=array();
		if ($this->namemodAbuelo==''){
			$arbol=$this->menu($padre['modelo'],$idpadre,$padre['label'],$this->namemodHijo, $this->modHijo->getTituloListado());
		}else{
			$dataMenu['listar']=false;
			$dataMenu['crear']=false;
			$arbol=$this->menu($this->namemodAbuelo,$idpadre,$this->namemodAbuelo,$this->namemodHijo, $this->modHijo->getTituloListado());
		}


		//******** Para las claves foraneas del padre
		recursion($this,$this->metaDataPadre,$this->dataPadre,$this->namemodPadre);

		//necesita saber en que posicion se encuentran los datos de id
		$i=$this->modPadre->getIndexCampo($this->metaDataPadre,'id');

		//arma el vector de respuestas para cada pregunta
		$padres=array();
		$auxmetaDataHijo=array();
		$cantidadTotal=0;
		foreach($this->dataPadre as $padre){
			//print_r($this->dataPadre);
			$this->modHijo->setCondicion($this->modPadre->getIdKey(),$padre[$i]);
			if (count($this->dataPadre) != 1 ){
				$dataHijos=$this->modHijo->secProxy('getData');
			} else {
				$dataHijos=$this->modHijo->secProxy('getData',$this->cantidadPorPagina, $this->paginaActual);
				$cantidadTotal = $this->modHijo->getCantidadRegistros();
			}
			$auxmetaDataHijo=$this->metaDataHijo;
			recursion($this,$auxmetaDataHijo,$dataHijos,$this->namemodHijo);
			$padres[]=array('datahijos'=>$dataHijos,
					   'datapadre'=>$padre);
		}




		// Arma el array que será utilizado por la vista
		$visual=array('titulo_pagina'=>	$this->tituloListado,
				'idabuelo'=>$idpadre,
				'modhijo'=>$this->nombreModelo,
				'metadatahijos'=>$auxmetaDataHijo,
				'metadatapadre'=>$this->metaDataPadre,
				'modpadre'=>$this->namemodPadre,
				'padres'=>$padres,
				'extras'=>$this->modelo->getExtras(),
				'arbol'=>$arbol);

		if ($sinabuelo){
			//$this->tituloListado = $this->modAbuelo->getTituloListado();
			$url = site_url('conquer/listar/'.$this->nombreModelo.'/'.$idpadre.'/1/p/');
			$config = $this->paginacion($url,$this->cantidadPorPagina,$cantidadTotal,7 );
		} else {
			$url = site_url('conquer/listar/'.$this->nombreModelo.'/'.$idpadre.'/p/');
			$config = $this->paginacion($url,$this->cantidadPorPagina,$cantidadTotal,6 );
		}
		//Se inicializa la paginacion correspondiente.
		
		$this->pagination->initialize($config);
		//$data['links'] = $this->pagination->create_links();
		$visual['links'] = $config;
		
		
		$dataMenu['hijosModelo'] =$this->modHijo->getHijos();

		$dataMenu['modelo'] = $this->nombreModelo;
		$dataMenu['idabuelo'] = $idpadre;
		$dataMenu['idpadre'] = $idpadre;
		$dataMenu['listar'] = $this->modHijo->mostrarOpcionListar();
		$dataMenu['crear'] = $this->modHijo->mostrarOpcionCrear();
		$dataMenu['buscar'] = $this->modHijo->mostrarOpcionBuscar();

		$this->load->view('conquer/cabecera');
		$this->load->view('conquer/navegacion');
		$this->load->view($this->carpetaVista.'opciones',$dataMenu);
		$this->load->view($this->carpetaVista.'error');
		if ($this->namemodAbuelo!=""){
			$this->load->view($this->carpetaVista.'listadoparte',$visual);
		} else {
			$this->load->view($this->carpetaVista.'listadosinabuelo',$visual);
		}
		$this->load->view('conquer/pie');

	}

	// =================================================
	/**
	 * Listado donde se puede elegir el padre para visualizar sus hijos
	 * @param $padre
	 * @return unknown_type
	 */
	private function seleccionDePadre($padre) {

		$this->namemodPadre=$padre['modelo'];
		$this->load->model($this->namemodPadre,'modPadre');
		$aux=$this->modPadre->getPartof();
		if (!empty($aux)) $padre=$aux; //?


		//$config = $this->modelo->secProxy('paginacion');
		//$data['titulo_pagina'] =$padre['label']."<br />";
		$data['titulo_pagina'] = 'Seleccione el/la '.$padre['modelo'].' de la cual quiere mostrar un/a '.$this->nombreModelo;
		$data['modelo'] = $padre['modelo'];
		$this->load->model($padre['modelo'],'modpadre');
		$data['metaData'] = $this->modpadre->getMetaData();
		$data['resultado'] = $this->modpadre->secProxy('getData',$this->cantidadPorPagina, $this->paginaActual);
		$cantidadTotal = $this->modpadre->getCantidadRegistros();
		$data['modoriginal'] = $this->nombreModelo;
		$data['hijosModelo'] = $this->modelo->getHijos();
		//******** Para las claves foraneas


		$dataMenu['modelo'] = $this->nombreModelo;
		$dataMenu['idpadre'] = 0;
		$dataMenu['listar'] = $this->modpadre->mostrarOpcionListar();
		$dataMenu['crear'] = $this->modpadre->mostrarOpcionCrear();
		$dataMenu['buscar'] = $this->modpadre->mostrarOpcionBuscar();
		
		$url = site_url('conquer/listar/'.$this->nombreModelo.'/'.$padre['modelo'].'/p/');
		$config = $this->paginacion($url,$this->cantidadPorPagina,$cantidadTotal,6 );
		//Se inicializa la paginacion correspondiente.
		$this->pagination->initialize($config);
		//$data['links'] = $this->pagination->create_links();
		$data['links'] = $config;


		//echo '<pre>'; print_r($this->sesion->userdata('privilegios')); echo '</pre>';
		

		$this->load->view($this->carpetaVista.'cabecera');
		$this->load->view($this->carpetaVista.'navegacion');
		//$this->load->view($this->carpetaVista.'opciones',$dataMenu);
		$this->load->view($this->carpetaVista.'error');
		$this->load->view($this->carpetaVista.'listado',$data);
		$this->load->view($this->carpetaVista.'pie');
	}


	/**
	 * 
	 * @return unknown_type
	 */
	function paginacion($url, $cantidadPorPagina, $cantidadTotal, $segmento)
	{
		//$config['base_url'] = site_url('conquer/listar/').'/'.$this->uri->segment(3); // FIX4ME MAL

		$config['base_url'] = $url;
		$config['total_rows'] = $cantidadTotal;
		$config['num_links'] = 2;
		$config['per_page'] = $cantidadPorPagina;
		$config['uri_segment'] = $segmento;
		$config['first_link'] = 'Primero';
		$config['last_link'] = '&Uacute;ltimo';
		return $config;
	}

	// =================================================
	/**
	 * Devuelve el Formulario del modelo especificado
	 * para ser completado por el usuario
	 * @param $model
	 * @param $id
	 * @param $idpadre
	 * @return unknown_type
	 */
	function frcrear($model,$id=0,$idpadre=0) {

		// Verificar que se selecciono un modelo para listar, sino enviarlo al home
		if (empty($model)) {
			$this->sesion->set_userdata('error',"<p>Error: Falta especificar que es lo que se desea crear.</p>");
			redirect($this->carpetaVista.'home');
			exit(0);
		}

		//Luego de modificar o crear, vuelve a adonde estaba cuando se invocó la acción
		if (isset($_SERVER['HTTP_REFERER'])){

			// Si no encuentra la palabre frcrear, significa que es lo que le interesa crear
			if (strstr($_SERVER['HTTP_REFERER'],'frcrear'.'/'.$model)==false) {
				$this->sesion->set_userdata('redirecciona',$_SERVER['HTTP_REFERER']);
			}

		}else{
			// Si la encuentra es que apreto submit de crear
			$this->sesion->set_userdata('redirecciona','conquer/listar/'.$model);
		}
		$this->load->model($model,'mod');
		$arbol=array();
		//Si tiene padre mustra cual es y el menu
		if ($idpadre!=0){
			$sinabuelo=$this->mod->getTipoListado(); 
			$padre = $this->mod->getPartof();
			$this->namemodHijo=$model;
			backtrack($this,$idpadre,1); //el padre nunca es el abuelo, siempre es padre
			//Carga el Arbol de navegacion
			$arbol=$this->menuCrear($padre['modelo'],$idpadre,$padre['label'],$this->namemodHijo, $this->modHijo->getTituloListado());

		}
//echo '<pre>';print_r($arbol);echo '</pre>'; exit;

		
		$this->modelo =& $this->mod;

		$this->tituloCrear = $this->modelo->getTituloCrear();
		$this->tituloModificar = $this->modelo->getTituloModificar();

		$datosPersona = array();
		//Si id es 0, se está creando, sino se está modificando
		if ($id <> 0){
			$datosPersona = $this->modelo->secProxy('getRow',$id);	//se traen los datos de la entidad a modificar
			$dataContenido['titulo_pagina'] = $this->tituloModificar;
		}else{
			$dataContenido['titulo_pagina'] = $this->tituloCrear;
		}


		//*** Se cargan las reglas de validacion del modelo principal
		$this->load->library('validation');
		$rules=$this->modelo->validacion();
		$fields=$this->modelo->fields();


		//Datos que se van a utilizar en las vistas, se obtienen del modelo. Así las vistas pueden ser genericas.
		$dataMenu['modelo'] = $model;
		$dataMenu['idpadre'] = $idpadre;
		$dataMenu['listar'] = $this->modelo->mostrarOpcionListar();
		$dataMenu['crear'] = $this->modelo->mostrarOpcionCrear();
		$dataMenu['buscar'] = $this->modelo->mostrarOpcionBuscar();
		
		$dataContenido['id'] = $id;
		$dataContenido['idkey'] = $this->modelo->getIdKey();
		$dataContenido['modelo'] = $model;
		$dataContenido['campos'] = $this->modelo->getRowMetaData();
		$dataContenido['arbol'] = $arbol;

		//******** Para las claves foraneas
		$auxCampos=array();
		$auxRules=array();
		$auxFields=array();
		$auxDatosPersona=array();
		
		
		/*
		 * Cuando un campo tiene una key estatico definido con 
		 * 1 => entonces para cualquier tipo de usuario el dato es estatico 
		 * 2 => entonces solo para los tipo de usuarios que pueden editar solo sus propios datos
		 * (tipo 2) el dato es estatico
		 */ 
		foreach($dataContenido['campos'] as &$campo){
			if ($campo['clase'] == 'foranea'){
				$this->load->model($campo['modelo']);
				$auxCampos=array_merge($auxCampos,$this->$campo['modelo']->getRowMetaData());
				$auxRules=array_merge($auxRules,$this->$campo['modelo']->validacion());
				$auxFields=array_merge($auxFields,$this->$campo['modelo']->fields());
				if ($id <> 0){
					$auxDatosPersona=array_merge($auxDatosPersona,$this->$campo['modelo']->secProxy('getRow',$datosPersona[$campo['realname']]));
				}
			}
			// Si se esta creando, no usar, solo al modificar
			if ($id!=0){
				if (isset($campo['estatico'])) {
					if ($campo['estatico'] == 1) {
						//break;
						//$campo['realname']
						$rules[$campo['realname']] = str_replace("required",'',$rules[$campo['realname']]);
						$campo['clase'] = 'estatico';
					} elseif ($campo['estatico'] == 2){
						$tipoPermiso = $this->sesion->existe(array('privilegios',strtolower($model),'modificar'));
						if ($tipoPermiso != 1){
							//break;
							$rules[$campo['realname']] = str_replace("required",'',$rules[$campo['realname']]);
							$campo['clase'] = 'estatico';
						}
					}
				}
			}
		}
		
		
		$dataContenido['campos'] = array_merge($dataContenido['campos'],$auxCampos);
		$rules = array_merge($rules,$auxRules);
		$fields = array_merge($fields,$auxFields);
		$datosPersona = array_merge($datosPersona,$auxDatosPersona);
		//******** Fin claves foraneas

		// Se incorporan las reglas de validacion
		$this->validation->set_rules($rules);
		$this->validation->set_fields($fields);
		/*
		 echo '<pre>';
		 print_r($dataContenido);
		 echo '<pre>';
		 */
		$dataContenido['idpadre']=$idpadre;
		foreach($dataContenido['campos'] as &$campo){
			switch ($campo['clase']) {
				case 'estatico': break;
				case 'partof':
					if ($idpadre!=0){
						$campo['value'] = $idpadre;
						break;
					}else{
						$campo['clase']='opciones';
					}
				case 'opciones':
					$this->load->model($campo['modelo']);
					$campo['opciones'] =$this->$campo['modelo']->secProxy('getIdNombre');
					//print_r($campo['opciones']);
					if ($id <> 0 && !empty($datosPersona)){
						$campo['default'] = $datosPersona[$campo['realname']];
					}
					break;
				default:
					if ($id <> 0 && !empty($datosPersona)){
						//echo '<pre>'; print_r($datosPersona); echo '</pre>';
						//echo 'Datos persona no esta empty'.$campo['value'];
						$campo['value'] = $datosPersona[$campo['realname']];
					}else{
						//echo 'Datos persona empty'.$campo['realname'];
						$var = $this->input->post($campo['realname']);
						$campo['value'] = ($var!='')?$var:'';
					}
			}
		}

		$dataCabecera['basico'] = false; 
		
		
		// Si van mal las reglas de validacion, carga la vista con el formulario.
		if ($this->validation->run() === FALSE)
		{
			$this->load->view($this->carpetaVista.'cabecera',$dataCabecera);
			$this->load->view($this->carpetaVista.'navegacion');
			$this->load->view($this->carpetaVista.'opciones',$dataMenu);
			$this->load->view($this->carpetaVista.'error');
			$this->load->view($this->carpetaVista.'frcrear',$dataContenido);
			$this->load->view($this->carpetaVista.'pie');
		}
		else   // Si van bien las reglas de validacion, inserta o modifica los datos.
		{
			$retornoUp=array();
			$file=array();
			$errorUp='';
			foreach($dataContenido['campos'] as $campor){
				if ($campor['clase']=='file'){
					/*
					 * 0: Reemplazar info del campo por el nuevo archivo
					 * 1: Eliminar info del campo
					 * 2: Mantener igual
					 */
					$del_accion = $this->input->post('del_'.$campor['realname'],'2');
					switch ($del_accion){
						case '0':
							$this->load->library('upload');
							$path= isset($campor['path'])?$campor['path']:null;
							$retornoUp=$this->do_upload($model,$campor['realname'],$campor['types'],$path);
							$file[$campor['realname']]=$retornoUp['nombreArchivo'];
							$errorUp= $retornoUp['error'];
							break;
						case '1':
							$file[$campor['realname']]='';
							break;
						case '2':
						default:
							//echo 'sas';
							//exit();
							break;
					}
					//echo $errorUp;
					//break;
					//TODO reportar error de archivo
				}
			}

			if ($id==0){
				//Antes de insertar en el modelo ppal, debe insertar las claves foraneas (1 nivel solo)
				$foreign=$this->modelo->preparaInsertar();
				$foreignIds=array();
				foreach($foreign as $mod){
					$this->load->model($mod);
					$foreignIds[$mod]=$this->$mod->secProxy('insertar',array(),$this); //inserta en el modelo foraneo y obtiene el id
				}
				//Recien ahora puede insertar en el modelo ppa, dado que ya tiene los ids foraneos.
				$this->modelo->secProxy('insertar',$foreignIds,$file,$this);

			} else {
				//modifica el modelo ppal
				//print_r($file);
				$aux=$this->modelo->secProxy('modificar',$file,$this);
				//modifica los modelos foraneos (1 nivel solo)
				foreach($aux as $mod){
					echo 'rrr ';
					$this->load->model($mod);
					$this->$mod->secProxy('modificar',null,$this);
				}
			}

			redirect($this->sesion->userdata('redirecciona'));

		}


	}


	/**
	 * Subir archivo
	 * @param $modelo
	 * @param $campo
	 * @param $types
	 * @return unknown_type
	 */
	private function do_upload($modelo,$campo,$types,$path=null)
	{
		$config= array();
		$config['allowed_types'] = $types;
		if (empty($path)){
			$config['upload_path'] = './uploads/'.strtolower($modelo);
		}else{
			$config['upload_path'] = $path;
		}

		$config['max_size'] = '1000';
		$this->upload->initialize($config);
		$nombreArchivo = '';
		$error = '';

		if ( ! $this->upload->do_upload($campo))
		{
			$this->sesion->set_userdata('error',$this->upload->display_errors());
			$error= $this->upload->display_errors();
		} else {
			$filedata = $this->upload->data();
			$nombreArchivo = $filedata['file_name'];
		}
		//echo $nombreArchivo.' - ';
		$retorno = array('error'=>$error, 'nombreArchivo'=>$nombreArchivo );
		return $retorno;

	}

	/**
	 * Eliminar registro del modelo especificado
	 * @param $model
	 * @param $id
	 * @return unknown_type
	 */
	function eliminar($model,$id)
	{

		$this->load->model($model,'mod');
		$this->modelo =& $this->mod;
		$this->modelo->secProxy('eliminar',$id);
		
		redirect($this->carpetaVista.'listar/'.$model);

	}

	/**
	 * Busqueda de registros en el modelo indicado. Utiliza a la vista del modelo, en el caso de que esté declarada
	 * @param $model
	 * @param $aexcel : exporta a excel
	 * @return unknown_type
	 */
	function buscar($model,$aexcel=0)
	{
		//si existe la vista SQL, la carga, sino carga el modelo
		if(file_exists(APPPATH.'models/'.'view'.strtolower($model).'.php')){
			$this->load->model('view'.$model,'mod');
		}else{
			$this->load->model($model,'mod');
		}
		$data['metaData'] = $this->mod->getMetaData();
		$data['titulo_pagina']= $this->mod->getTituloListado();
		$data['modelo']=$model;
		$data['idkey']=$this->mod->getIdKey();

		$opciones=array();
		foreach ($data['metaData'] as $campo){
			$opciones[$campo['realname']]=$campo['label'];
			
		}
		$data['opciones']=$opciones;
		$data['order']=$this->mod->getIdKey();
		$data['opciones'][$this->mod->getIdKey()]="Identificador";

		$arrayEnc=array();
		$stringCol=array();
		if ($this->input->post('bus')){
			$arrayEnc[] = "Nro";
			$stringCol[] = $this->mod->getIdKey();
			foreach ($data['metaData'] as $campo){
				if ($this->input->post($campo['realname'])=='true'){
					$arrayEnc[]=$campo['label'];
					$stringCol[]=$campo['realname'];
					//$opciones[$campo['realname']]=$campo['label'];
				}
			}

			$where='';
//echo 		mysql_real_escape_string($this->input->post('operadorFiltro')); exit;	
			if($this->input->post('textoFiltro')!=''){
				$not='';
				if ($this->input->post('notFiltro')) $not='NOT';
				$where=mysql_real_escape_string($this->input->post('comboFiltro')).'  '.$not.' '.mysql_real_escape_string($this->input->post('operadorFiltro')).' "%'.mysql_real_escape_string($this->input->post('textoFiltro')).'%"'.' ';
			}
			if($this->input->post('textoFiltro2')!=''){
				$not='';
				if ($this->input->post('notFiltro3')) $not=' NOT';
				if (!empty($where)) $where=$where.mysql_real_escape_string($this->input->post('unidor12')).' ';
				$where=$where.mysql_real_escape_string($this->input->post('comboFiltro2')).$not.' '.mysql_real_escape_string($this->input->post('operadorFiltro2')).' "%'.mysql_real_escape_string($this->input->post('textoFiltro2')).'%"'.' ';
			}
			if($this->input->post('textoFiltro3')!=''){
				$not='';
				if ($this->input->post('notFiltro3')) $not=' NOT';
				if (!empty($where)) $where=$where.mysql_real_escape_string($this->input->post('unidor12')).' ';
				$where=$where.mysql_real_escape_string($this->input->post('comboFiltro3')).$not.' '.mysql_real_escape_string($this->input->post('operadorFiltro3')).' "%'.mysql_real_escape_string($this->input->post('textoFiltro3')).'%"';
			}
			$this->sesion->set_userdata('busstringCol',$stringCol);
			$this->sesion->set_userdata('buswhere',$where);
			$this->sesion->set_userdata('busorder',$this->input->post('order1').','.$this->input->post('order2'));
			$limit=$this->input->post('limit');
			$this->mod->setOrderBy($this->input->post('order1').','.$this->input->post('order2'));
			$aux=$this->mod->secProxy('busqueda_gen',$stringCol,$where,$limit);
			$tabla['contenido']=$aux['consulta'];
			$tabla['encabezado']=$arrayEnc;
			$data['tablas']=array($tabla);

//echo '<pre>'; print_r($tabla['contenido']); echo '</pre>'; exit();
		}elseif ($aexcel==0){
			$this->sesion->set_userdata('busstringCol',"");
			$this->sesion->set_userdata('buswhere',"");
		}

		if ($aexcel==0){
			$dataMenu['modelo'] = $model;
			$data['extras']=$this->mod->getExtras('buscar');
			$this->load->view($this->carpetaVista.'cabecera');
			$this->load->view($this->carpetaVista.'navegacion');
			$this->load->view($this->carpetaVista.'opciones',$dataMenu);
			$this->load->view($this->carpetaVista.'error');
			$this->load->view($this->carpetaVista.'buscar',$data);
			$this->load->view($this->carpetaVista.'pie');
		}else{
			$stringCol=$this->sesion->userdata('busstringCol');
			$where=$this->sesion->userdata('buswhere');
			$this->mod->setOrderBy($this->sesion->userdata('busorder'));
			$aux=$this->mod->secProxy('busqueda_gen',$stringCol,$where);
			$tabla['contenido']=$aux['consulta'];
			$tabla['encabezado']=$arrayEnc;
			$data['tablas']=array($tabla);
			aCSV($data);
		}
		
	}

	
	/**
	 * Devuelve el menu de navegacion que se muestra sobre los listados
	 * @param $model
	 * @param $id
	 * @param $label
	 * @param $modhijo
	 * @param $labelh
	 * @return array
	 */
	private function menu($model,$id,$label='',$modijo, $labelh)
	{
		$this->load->model($model);
		$datos=$this->$model->secProxy('getRow',$id);
		$array= array('id'=>$id,'nombre'=>$datos[$this->$model->getNombreCampo()], 'label'=>$label, 'modijo'=>$modijo, 'modelo'=> $model, 'labelh'=>$labelh);
		$bigArray=array($array);		
		$padre=$this->$model->getPartof();
		if(empty($padre)){
			return $bigArray;
		}else{
			return array_merge($this->menu($padre['modelo'],$datos[$padre['realname']],$padre['label'],$model,$this->$model->getTituloListado()),$bigArray);
		}
	}


	/**
	 * Devuelve el menu de navegacion que se muestra sobre el formulario de crear/modificar
	 * @param $model
	 * @param $id
	 * @param $label
	 * @param $modhijo
	 * @param $labelh
	 * @return array
	 */
	private function menuCrear($model,$id,$label='',$modijo, $labelh)
	{
		$sinabuelo=$this->mod->getTipoListado();
		$this->load->model($model);
		$datos=$this->$model->secProxy('getRow',$id);
		$padre=$this->$model->getPartof();
		$abuelo=null;
		$nombre=$datos[$this->$model->getNombreCampo()];
		if (!$sinabuelo && !empty($padre)){
			$id=$datos[$padre['realname']];
			$label=$padre['label'];
			$this->load->model($padre['modelo']);
			$abuelo=$this->$padre['modelo']->secProxy('getRow',$id);
			$nombre=$abuelo[$this->$padre['modelo']->getNombreCampo()];
			$padre2=$this->$padre['modelo']->getPartof();
		}
		$array= array('id'=>$id,'nombre'=>$nombre, 'label'=>$label, 'modijo'=>$modijo, 'modelo'=> $model, 'labelh'=>$labelh);
		$bigArray=array($array);		
		if(empty($padre)){
			return $bigArray;
		}else{
			if (!$sinabuelo){	
				return array_merge($this->menu($padre2['modelo'],$abuelo[$padre2['realname']],$padre2['label'],$padre['modelo'],$this->$padre['modelo']->getTituloListado()),$bigArray);
			}
			return array_merge($this->menu($padre['modelo'],$datos[$padre['realname']],$padre['label'],$model,$this->$model->getTituloListado()),$bigArray);
		}
	}

	/**
	 * Muestra todos los datos de un elemento y sus hijos
	 * @param $model
	 * @param $id
	 * @return array
	 */
	function detalle($model,$id)
	{
		/*$this->sesion->set_userdata('expaderPrimerItem',true);
		$this->load->model($modelo,'mod');
		$pos = $this->mod->secProxy('getPosicion',$id);
		redirect('conquer/listar/'.$modelo.'/p/'.$pos);*/
		$model=strtolower($model);


		$metadatos=array();
		$datos=$this->getInto($model,$id,$metadatos);

		$dataMenu['modelo'] = $model;
		$padre=$this->$model->getPartof();
		$dataMenu['idpadre'] = (!empty($padre) && isset($datos['nodo'][$padre['realname']]))?$datos['nodo'][$padre['realname']]:0; 
		$dataMenu['listar'] = $this->$model->mostrarOpcionListar();
		$dataMenu['crear'] = $this->$model->mostrarOpcionCrear();
		$dataMenu['buscar'] = $this->$model->mostrarOpcionBuscar();
//echo '<pre>'; print_r($datos); echo '</pre>';exit;
		
		$visual= array();
		$visual['datos']=$datos;
		$visual['metadatos']=$metadatos;
		$visual['titulo_pagina']='Detalle';
		$visual['idItem']='0';
		$dataCabecera['rounded'] = true; 

		$this->load->view('conquer/cabecera',$dataCabecera);
		$this->load->view('conquer/navegacion');
		$this->load->view($this->carpetaVista.'opciones',$dataMenu);
		$this->load->view($this->carpetaVista.'error');
		$this->load->view($this->carpetaVista.'detalle',$visual);
		$this->load->view('conquer/pie');


	}

	/**
	 * Devuelve los datos del elemento junto con los datos de todos sus hijos, haciendo una buscqueda en profundidad
	 * @param $model
	 * @param $id
	 * @return array
	 */
	private function getInto($model,$id,&$metadatos)
	{
		$data=array();
		$this->load->model($model);
		$data['nodo']=$this->$model->secProxy('getRow',$id);
		$data['extras'] = $this->$model->getExtras();
		$hijos=$this->$model->getHijos();
		$auxHijos=array();
		$data['modelo']=$model;
		if(!isset($metadatos[$model])) $metadatos[$model]=$this->$model->getCamposKey();
		foreach ($hijos as $keyHijo=>$titHijo){
			$auxHijos2=array();
			$hijoReal=$this->getRealSun($keyHijo,$model);
			$this->load->model($hijoReal);
			$camposReq=array($this->$hijoReal->getIdKey(),$this->$hijoReal->getNombreCampo());
			$nodos=$this->$hijoReal->secProxy('busqueda_gen',$camposReq,$this->$model->getIdKey().' = '.$id);
			foreach($nodos['consulta'] as $ids){
				$auxHijos2[$ids[$this->$hijoReal->getNombreCampo()]]=$this->getInto($hijoReal,$ids[$this->$hijoReal->getIdKey()],$metadatos);
			}
			$auxHijos[$hijoReal]=array($titHijo,$auxHijos2);
			
		}
		$data['hijos']=$auxHijos;
		return $data;
		
	}

	/**
	 * Usada por getInto, se fija si es el hijo verdadero o el nieto
	 * @param $model
	 * @param $id
	 * @return array
	 */
	private function getRealSun($keyHijo,$padre)
	{
		$this->load->model($keyHijo);
		$partOf=$this->$keyHijo->getPartof();
//echo '<pre>';print_r ($partOf);
		if (empty($partOf))
			return $keyHijo;
		if ($partOf['modelo']==$padre)
			return $keyHijo;
		return $partOf['modelo'];
	}


	/**
	 * Usada para modelos que surgen de relaciones entre modelos
	 * @param $model = modelo axb
	 * @param $relacion = puede ser 1a1, 1aN, Na1, NaN
	 * @param $ida = id opcional del elemento único
	 */	
	function asignar($model,$relacion,$ida=0)
	{
		$this->load->model($model);
		$metadata=$this->$model->getMetaData();
		$elementoA=NULL;
		$elementoB=NULL;
		foreach($metadata as $key=>&$elem){
			if (isset($elem['axb'])){
				if ($elem['axb']=='a') 
					$elementoA=$elem;
				else
					$elementoB=$elem;
				unset($metadata[$key]);
			}else{
				if ($elem['clase']=='id') unset($metadata[$key]);
				if ($elem['clase']=='opciones'){
					$this->load->model($elem['modelo']);
					$elem['opciones'] =$this->$elem['modelo']->secProxy('getIdNombre');
				}
			}
		}

		if (empty($elementoA) || empty($elementoB)) exit('Error en el modelo');

		$data['campos']=$metadata;
		$data['relacion']=$relacion;
		$data['model']=$model;

		//relacion Na1 se dan vuelta para que sean 1aN
		if ($relacion=='Na1'){
			$aux= $elementoA;
			$elementoA=$elementoB;
			$elementoB=$aux;
			$relacion='1aN';
		}

		//Carga de variables necesarias
		$this->load->model($elementoA['modelo'], 'modeloa');
		$this->load->model($elementoB['modelo'], 'modelob');
		$datosA=array();
		$datosB=array();
		$camposBusquedaA=$this->modeloa->getCamposBusqueda();
		$camposBusquedaB=$this->modelob->getCamposBusqueda();

		//Chequea el parámetro
		if ($ida>0) { //si A se lo pasan por parámetro
			$aux=$this->modeloa->secProxy('getRow',$ida);
			$datosA[$aux[$this->modeloa->getIdKey()]]=$aux;

		}else{ //si A viene de una búsqueda
			$parametro=array();
			foreach ($camposBusquedaA as $campoa=>$labela){
				$valorA=$this->input->post('A__'.$campoa);
				if(!empty($valorA)) $parametro[$campoa.' like']='%'.$valorA.'%';
			}

			$this->modeloa->setOrderBy($this->modeloa->getIdKey().' DESC');
			$this->modeloa->setKeyField(TRUE);

			if(!empty($parametro)) {
				$this->modeloa->setCondicion($parametro);
				$datosA=$this->modeloa->secProxy('getData');
			}else{
				$datosA=$this->modeloa->secProxy('getData',10,0);
			}
		}

		//B viene si o si de una búsqueda
		$parametro=array();
		foreach ($camposBusquedaB as $campob=>$labelb){
			$valorB=$this->input->post('B__'.$campob);
			if(!empty($valorB)) $parametro[$campob.' like']='%'.$valorB.'%';
		}

		$this->modelob->setOrderBy($this->modelob->getIdKey().' DESC');
		$this->modelob->setKeyField(TRUE);

		if(!empty($parametro)) {
			$this->modelob->setCondicion($parametro);
			$datosB=$this->modelob->secProxy('getData');
		}else{
			$datosB=$this->modelob->secProxy('getData',10,0);
		}

		
		//Si ya tiene que asignar
		if ($this->input->post('P__Enviar')=='Asignar'){
			$this->sesion->set_userdata('error',"<p>Se han hecho las asignaciones correctamente.</p>");
			$idelementosA=$this->input->post('A__opciones');
			$idelementosB=$this->input->post('B__opciones');
			$datosDemas=array();
			foreach ($metadata as $md){
				$datosDemas[$md['realname']]=$this->input->post($md['realname']);
			}
			switch ($relacion){
				case '1a1':
					if (!is_numeric($idelementosA) || !is_numeric($idelementosB)) break;
					$insertar=array($elementoA['realname']=>$idelementosA, $elementoB['realname']=>$idelementosB);
					$insertar=array_merge($insertar,$datosDemas);
					$this->$model->secProxy('insertarSinPost',$insertar);
					break;
				case '1aN': 
					if (!is_numeric($idelementosA) || !is_array($idelementosB)) break;
					foreach($idelementosB as $keyB=>$idelemB){
						$insertar=array($elementoA['realname']=>$idelementosA, $elementoB['realname']=>$keyB);
						$insertar=array_merge($insertar,$datosDemas);
						$this->$model->secProxy('insertarSinPost',$insertar);
					}
					break;
				case 'NaN':
				default:
					if (!is_array($idelementosA) || !is_array($idelementosB)) break;
					foreach($idelementosA as $keyA=>$idelemA){
						foreach($idelementosB as $keyB=>$idelemB){
							$insertar=array($elementoA['realname']=>$keyA, $elementoB['realname']=>$keyB);
							$insertar=array_merge($insertar,$datosDemas);
							$this->$model->secProxy('insertarSinPost',$insertar);
						}
					}
					break;
			}

		}

		
		$data['titulo_pagina'] = 'Agregar '.$elementoA['label'].' a '.$elementoB['label'];

		$data['elementoA']=$elementoA;
		$data['elementoB']=$elementoB;
		$data['camposBusquedaA']=$camposBusquedaA;
		$data['camposBusquedaB']=$camposBusquedaB;
		$data['ida']=$ida;
		$data['datosA']=$datosA;
		$data['datosB']=$datosB;
//echo '<pre>'; print_r($datosA);print_r($datosB);exit;

		$dataCabecera['rounded'] = true; 
		$dataCabecera['basico'] = false; 

		$this->load->view($this->carpetaVista.'cabecera',$dataCabecera);
		$this->load->view($this->carpetaVista.'navegacion');
		$this->load->view($this->carpetaVista.'asignar',$data);
		$this->load->view($this->carpetaVista.'error');
		$this->load->view($this->carpetaVista.'pie');
	}
}



?>
